package net.kleinhenz.norabase.client.datasource;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.fields.DataSourceIntegerField;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.widgets.grid.ListGridRecord;

import java.util.HashMap;
import java.util.Map;

import net.kleinhenz.norabase.shared.SortOrientation;
import net.kleinhenz.norabase.shared.TextMatchStyle;
import net.kleinhenz.norabase.shared.model.Battlegroup;
import net.kleinhenz.norabase.shared.model.FetchResult;
import net.kleinhenz.norabase.shared.model.Rune;

public class BattlegroupListDS extends GwtRpcDataSource {

	private String accountId = null;
	
    public BattlegroupListDS(String accountId) {

    	// FIXME
        DataSourceField field;
        field = new DataSourceIntegerField ("id", "Id");
        field.setPrimaryKey (true);
        field.setRequired(false);
        field.setCanEdit(false);
        field.setHidden(true);
        addField(field);
        
        field = new DataSourceTextField ("name", "Name");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        field = new DataSourceTextField ("creator", "Creator");
        field.setRequired(true);
        field.setCanEdit(false);
        addField(field);

        this.accountId = accountId;
    }

    public String getAccountId() {
    	return this.accountId;
    }
    
    @SuppressWarnings("unchecked")
	@Override
    protected void executeFetch (final String requestId, final DSRequest request, final DSResponse response) {

    	// aquiring meta data
    	final Map<String, SortOrientation> sortSpec = convertSortSpecifier(request.getSortBy());
        final int startIndex = (request.getStartRow() < 0)?0:request.getStartRow();
        final int endIndex = (request.getEndRow() == null)?-1:request.getEndRow();
        final TextMatchStyle textMatchStyle = convertTextMatchStyle(request.getTextMatchStyle());
        final Map<String, Object> criteria = request.getCriteria().getValues();
        
        // server connection
        BattlegroupListDSServiceAsync service = GWT.create (BattlegroupListDSService.class);
        service.fetch(startIndex, endIndex, sortSpec, textMatchStyle, criteria, getAccountId(), 
        		new AsyncCallback<FetchResult<Battlegroup<Rune>>>() {
            public void onFailure(Throwable caught) {
                response.setStatus(RPCResponse.STATUS_FAILURE);
                processResponse(requestId, response);
            }
            public void onSuccess(FetchResult<Battlegroup<Rune>> result) {
                ListGridRecord[] list = new ListGridRecord[result.size()];
                if (result.size() > 0) {
                    for (int i = 0; i < result.size(); i++) {
                        ListGridRecord record = new ListGridRecord ();
                        copyValues(result.get(i), record);
                        list[i] = record;
                    }
                }
                response.setData(list);
                // IMPORTANT: for paging to work we have to specify size of full result set
                response.setTotalRows(result.size());
                processResponse(requestId, response);
            }

            private void copyValues(Battlegroup<Rune> from, ListGridRecord to) {
            	to.setAttribute("id", from.getId());
            	to.setAttribute("name", from.getName());
            	to.setAttribute("creator", from.getAccountId());
			}
        });
    }

	protected Map<String, SortOrientation> convertSortSpecifier(com.smartgwt.client.data.SortSpecifier[] sortSpecifiers) {

		Map<String, SortOrientation> sp = new HashMap<String, SortOrientation>();
		if (sortSpecifiers!=null)
			for (com.smartgwt.client.data.SortSpecifier sortSpecifier : sortSpecifiers) {
			sp.put(sortSpecifier.getField(), 
					SortOrientation.ASCENDING.equals(sortSpecifier.getSortDirection()) ? SortOrientation.ASCENDING : SortOrientation.DESCENDING);
		}
		return sp;
	}

	protected TextMatchStyle convertTextMatchStyle(com.smartgwt.client.types.TextMatchStyle textMatchStyle) {

    	if (com.smartgwt.client.types.TextMatchStyle.EXACT.equals(textMatchStyle))
    		return TextMatchStyle.EXACT;
    	else if (com.smartgwt.client.types.TextMatchStyle.STARTS_WITH.equals(textMatchStyle))
    		return TextMatchStyle.STARTS_WITH;
    	else if (com.smartgwt.client.types.TextMatchStyle.SUBSTRING.equals(textMatchStyle))
    		return TextMatchStyle.SUBSTRING;
    	else
    		throw new RuntimeException("Unknown TextMatchStyle " + textMatchStyle.toString());
    }

	@Override
	protected void executeAdd(String requestId, DSRequest request,
			DSResponse response) {
		// not implemented
	}

	@Override
	protected void executeUpdate(String requestId, DSRequest request,
			DSResponse response) {
		// not implemented
	}

	@Override
	protected void executeRemove(String requestId, DSRequest request,
			DSResponse response) {
		// not implemented
	}
}
